﻿
#region Usings
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endregion

namespace FasterWPF
{
    public static class CommonDatabinding
    {
        #region DataBinding

        #region #1. Container to Parent (direct)

        /// <summary>
        ///  DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to a Property on the Parent (T)
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnParentThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindContainersPropertyToParents<K, T>(this Border border, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnParentThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        ///  DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to a Property on the Parent (T) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnContainer"></param>
        /// <param name="depPropertyOnParentThatContainerBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindContainersPropertyToParents<K, T>(this Border border, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnParentThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #2. Child to Child (requires InnerChain)

        /// <summary>
        /// DataBind One Child's Property (Child K) to Another Child's Property (Child Z)
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="Z"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="rowZ"></param>
        /// <param name="columnZ"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnZThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToAnother<K, Z, T>(this InnerChain<T> chain, int rowK, int columnK, int rowZ, int columnZ, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnZThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where Z : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToAnother<K, Z, T>(chain.Item2, rowK, columnK, rowZ, columnZ, depPropertyOnK, depPropertyOnZThatKBindsTo, uSourceTrigger, bMode);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToAnother<K, Z, T>(this ContentControl chain, string key, int rowK, int columnK, int rowZ, int columnZ, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnZThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where Z : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;
            string row_colZ = "_" + rowZ + "_" + columnZ;
            string fullKeyZ = key + row_colZ;

            K kTemp = (K)ChildLookupDict[fullKeyK];
            Z zTemp = (Z)ChildLookupDict[fullKeyZ];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = zTemp,
                Path = new PropertyPath(depPropertyOnZThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            });
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to Another Child's Property (Child Z) with ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="Z"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="rowZ"></param>
        /// <param name="columnZ"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnZThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToAnother<K, Z, T>(this InnerChain<T> chain, int rowK, int columnK, int rowZ, int columnZ, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnZThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where Z : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToAnother<K, Z, T>(chain.Item2, rowK, columnK, rowZ, columnZ, depPropertyOnK, depPropertyOnZThatKBindsTo, uSourceTrigger, bMode, converter);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToAnother<K, Z, T>(this ContentControl chain, string key, int rowK, int columnK, int rowZ, int columnZ, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnZThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where Z : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;
            string row_colZ = "_" + rowZ + "_" + columnZ;
            string fullKeyZ = key + row_colZ;

            K kTemp = (K)ChildLookupDict[fullKeyK];
            Z zTemp = (Z)ChildLookupDict[fullKeyZ];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = zTemp,
                Path = new PropertyPath(depPropertyOnZThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            });
        }
        
        #endregion

        #region #3. Child to Parent (requires InnerChain)

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on the Parent (T)
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnParentThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToParents<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnParentThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToParents<K, T>(chain.Item2, rowK, columnK, depPropertyOnK, depPropertyOnParentThatKBindsTo, uSourceTrigger, bMode);
                return container;
            }));

            return chain;
        }
        
        public static void DataBindOneChildsPropertyToParents<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnParentThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on the Parent (T) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnParentThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToParents<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnParentThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToParents<K, T>(chain.Item2, rowK, columnK, depPropertyOnK, depPropertyOnParentThatKBindsTo, uSourceTrigger, bMode, converter);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToParents<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnParentThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger, 
                Converter = converter
            }
            );
        }

        #endregion

        #region #4. Border to Parent (direct)

        /// <summary>
        /// DataBind the Property of a Composite (Border) to a Property on the Parent (T)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnParentThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertyToParents<T>(this Border border, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnParentThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind the Property of a Composite (Border) to a Property on the Parent (T) with a Value Converter
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnParentThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindBordersPropertyToParents<T>(this Border border, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnParentThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = theParent,
                Path = new PropertyPath(depPropertyOnParentThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion
  
        #region #5. Parent to Container (direct)

        /// <summary>
        /// DataBind a Property on the Parent (T) to the Property of a Composite's Container (e.g. Grid in GridComposite) 
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnContainerThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindParentsPropertytoContainers<K, T>(this Border border, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnContainerThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        /// DataBind a Property on the Parent (T) to the Property of a Composite's Container (e.g. Grid in GridComposite) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnContainerThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindParentsPropertytoContainers<K, T>(this Border border, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnContainerThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }
        #endregion

        #region #6. Parent to Child (requires InnerChain)

        /// <summary>
        /// DataBind Property on the Parent (T) to One Child's Property (Child K)
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnKThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindParentsPropertyToOneChilds<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnKThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindParentsPropertyToOneChilds<K, T>(chain.Item2, rowK, columnK, depPropertyOnParent, depPropertyOnKThatParentBindsTo, uSourceTrigger, bMode);
                return container;
            }));

            return chain;
        }

        public static void DataBindParentsPropertyToOneChilds<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnKThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        ///  DataBind Property on the Parent (T) to One Child's Property (Child K) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnKThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindParentsPropertyToOneChilds<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnKThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindParentsPropertyToOneChilds<K, T>(chain.Item2, rowK, columnK, depPropertyOnParent, depPropertyOnKThatParentBindsTo, uSourceTrigger, bMode, converter);
                return container;
            }));

            return chain;
        }

        public static void DataBindParentsPropertyToOneChilds<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnKThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #7. Parent to Border (direct)

        /// <summary>
        /// DataBind a Property on the Parent (T) to the Property of a Composite (Border) 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnBorderThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindParentsPropertyToBorders<T>(this Border border, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnBorderThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = border,
                Path = new PropertyPath(depPropertyOnBorderThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        /// DataBind a Property on the Parent (T) to the Property of a Composite (Border) with a Value Converter
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnParent"></param>
        /// <param name="depPropertyOnBorderThatParentBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindParentsPropertyToBorders<T>(this Border border, DependencyProperty depPropertyOnParent, DependencyProperty depPropertyOnBorderThatParentBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            theParent.SetBinding(depPropertyOnParent, new Binding
            {
                Source = border,
                Path = new PropertyPath(depPropertyOnBorderThatParentBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #8. Container to Child (direct)

        /// <summary>
        /// DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to One Child's Property (Child K). T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="C"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnContainer"></param>
        /// <param name="depPropertyOnKThatContainerBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindContainersPropertyToOneChilds<K, C, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnKThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where C: FrameworkElement
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            C theContainer = theParent.GetContainerFromComposite<C, T>(b);

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];
 
            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to One Child's Property (Child K) with a Value Converter. T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="C"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnContainer"></param>
        /// <param name="depPropertyOnKThatContainerBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindContainersPropertyToOneChilds<K, C, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnKThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where C: FrameworkElement
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            C theContainer = theParent.GetContainerFromComposite<C, T>(b);

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];
 
            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #9. Child to Container (direct)

        /// <summary>
        /// DataBind One Child's Property (Child K) to the Property of a Composite's Container (e.g. Grid in GridComposite). T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="C"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnContainerThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindOneChildsPropertyToContainers<K, C, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnContainerThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where C : FrameworkElement
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            C theContainer = theParent.GetContainerFromComposite<C, T>(b);

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
         
        /// <summary>
        /// DataBind One Child's Property (Child K) to the Property of a Composite's Container (e.g. Grid in GridComposite) with a Value Converter. T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="C"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnContainerThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindOneChildsPropertyToContainers<K, C, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnContainerThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter) 
            where C : FrameworkElement
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            C theContainer = theParent.GetContainerFromComposite<C, T>(b);

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            });
        }

        #endregion

        #region #10. Container to Border (direct)

        /// <summary>
        /// DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to the Property of a Composite (Border)
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnContainer"></param>
        /// <param name="depPropertyOnBorderThatContainerBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindContainersPropertytoBorders<K, T>(this Border border, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnBorderThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = border,
                Path = new PropertyPath(depPropertyOnBorderThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        /// DataBind the Property of a Composite's Container (e.g. Grid in GridComposite) to the Property of a Composite (Border) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnContainer"></param>
        /// <param name="depPropertyOnBorderThatContainerBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindContainersPropertytoBorders<K, T>(this Border border, DependencyProperty depPropertyOnContainer, DependencyProperty depPropertyOnBorderThatContainerBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            theContainer.SetBinding(depPropertyOnContainer, new Binding
            {
                Source = border,
                Path = new PropertyPath(depPropertyOnBorderThatContainerBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #11. Border to Container (direct)

        /// <summary>
        /// DataBind the Property of a Composite (Border) to the Property of a Composite's Container (e.g. Grid in GridComposite) 
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnContainerThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertytoContainers<K, T>(this Border border, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnContainerThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind the Property of a Composite (Border) to the Property of a Composite's Container (e.g. Grid in GridComposite) with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnContainerThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindBordersPropertytoContainers<K, T>(this Border border, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnContainerThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = border.GetParentFromComposite<T>();
            K theContainer = theParent.GetContainerFromComposite<K, T>(border);

            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = theContainer,
                Path = new PropertyPath(depPropertyOnContainerThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #12. Child to Border (direct)

        /// <summary>
        /// DataBind One Child's Property (Child K) to the Property of a Composite (Border). T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnBorderThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindOneChildsPropertyToBorders<K, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnBorderThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = b,
                Path = new PropertyPath(depPropertyOnBorderThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to the Property of a Composite (Border) with a Value Converter. T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnBorderThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindOneChildsPropertyToBorders<K, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnBorderThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();
            
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = b,
                Path = new PropertyPath(depPropertyOnBorderThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion
        
        #region #13. Border to Child (direct)

        /// <summary>
        /// DataBind the Property of a Composite (Border) to One Child's Property (Child K). T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnKThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertyToOneChilds<K, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnKThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            b.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind the Property of a Composite (Border) to One Child's Property (Child K) with a Value Converter. T is the Parent.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="b"></param>
        /// <param name="key"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnKThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindBordersPropertyToOneChilds<K, T>(this Border b, string key, int rowK, int columnK, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnKThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter) 
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = b.GetParentFromComposite<T>();

            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            b.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = kTemp,
                Path = new PropertyPath(depPropertyOnKThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #14. Border to Framework Element Parameter (direct)

        /// <summary>
        /// DataBind the Property of a Border to a Property on a FrameworkElement parameter
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnParentThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertyToFE<FE>(this Border border, FrameworkElement fe, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnFEThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where FE : FrameworkElement
        {
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind the Property of a Border to a Property on a FrameworkElement parameter with a Value Converter
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="border"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnParentThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertyToFE<FE>(this Border border, FrameworkElement fe, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnFEThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where FE : FrameworkElement
        {
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        #endregion

        #region #15. Child to Framework Element Parameter (requires InnerChain, plus direct)
        
        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Framework Element Parameter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="FE"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="fe"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnFEThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToFE<K, FE, T>(this InnerChain<T> chain, int rowK, int columnK, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where FE : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToFE<K, FE, T>(chain.Item2, rowK, columnK, fe, depPropertyOnK, depPropertyOnFEThatKBindsTo, uSourceTrigger, bMode);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToFE<K, FE, T>(this ContentControl chain, string key, int rowK, int columnK, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where FE : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Framework Element Parameter with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="FE"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="fe"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnFEThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToFE<K, FE, T>(this InnerChain<T> chain, int rowK, int columnK, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where FE : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToFE<K, FE, T>(chain.Item2, rowK, columnK, fe, depPropertyOnK, depPropertyOnFEThatKBindsTo, uSourceTrigger, bMode, converter);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToFE<K, FE, T>(this ContentControl chain, string key, int rowK, int columnK, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where FE : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Framework Element Parameter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="FE"></typeparam>
        /// <param name="child"></param>
        /// <param name="fe"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnFEThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindOneChildsPropertyToFE<K, FE>(this K child, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where FE : FrameworkElement
        {
            child.SetBinding(depPropertyOnK, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Framework Element Parameter with a ValueConverter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="FE"></typeparam>
        /// <param name="child"></param>
        /// <param name="fe"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnFEThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindOneChildsPropertyToFE<K, FE>(this K child, FrameworkElement fe, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnFEThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where FE : FrameworkElement
        {
            child.SetBinding(depPropertyOnK, new Binding
            {
                Source = fe as FE,
                Path = new PropertyPath(depPropertyOnFEThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }
        #endregion

        #region #16. Border to Dependency Object Parameter (direct)

        /// <summary>
        /// DataBind the Property of a Border to a Property on a Dependency Object parameter
        /// </summary>
        /// <param name="border"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnDObjThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindBordersPropertyToDepObj(this Border border, DependencyObject depObj, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnDObjThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
        {
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
       
        /// <summary>
        ///  DataBind the Property of a Border to a Property on a Dependency Object parameter with a Value Converter
        /// </summary>
        /// <param name="border"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnBorder"></param>
        /// <param name="depPropertyOnDObjThatBorderBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindBordersPropertyToDepObj(this Border border, DependencyObject depObj, DependencyProperty depPropertyOnBorder, DependencyProperty depPropertyOnDObjThatBorderBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
        {
            border.SetBinding(depPropertyOnBorder, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatBorderBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            });
        }

        #endregion

        #region #17. Child to Dependency Object Parameter (requires InnerChain, plus direct)

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Dependency Object Parameter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnDObjThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToDepObj<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToDepObj<K, T>(chain.Item2, rowK, columnK, depObj, depPropertyOnK, depPropertyOnDObjThatKBindsTo, uSourceTrigger, bMode);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToDepObj<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
        
        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Dependency Object Parameter with a ValueConverter.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="chain"></param>
        /// <param name="rowK"></param>
        /// <param name="columnK"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnDObjThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static InnerChain<T> DataBindOneChildsPropertyToDepObj<K, T>(this InnerChain<T> chain, int rowK, int columnK, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            chain.Item3.Add(((container) =>
            {
                container.DataBindOneChildsPropertyToDepObj<K, T>(chain.Item2, rowK, columnK, depObj, depPropertyOnK, depPropertyOnDObjThatKBindsTo, uSourceTrigger, bMode, converter);
                return container;
            }));

            return chain;
        }

        public static void DataBindOneChildsPropertyToDepObj<K, T>(this ContentControl chain, string key, int rowK, int columnK, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)
            where K : FrameworkElement
            where T : FrameworkElement
        {
            T theParent = chain.GetTFromChildContentControl<T>();
            var ChildLookupDict = theParent.GetChildLookupDictionary();
            string row_colK = "_" + rowK + "_" + columnK;
            string fullKeyK = key + row_colK;

            K kTemp = (K)ChildLookupDict[fullKeyK];

            kTemp.SetBinding(depPropertyOnK, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }

        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Dependency Object Parameter
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <param name="child"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnDObjThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        public static void DataBindOneChildsPropertyToDepObj<K>(this K child, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode)
            where K : FrameworkElement
        {
            child.SetBinding(depPropertyOnK, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger
            }
            );
        }
   
        /// <summary>
        /// DataBind One Child's Property (Child K) to Property on Dependency Object Parameter with a ValueConverter.
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <param name="child"></param>
        /// <param name="depObj"></param>
        /// <param name="depPropertyOnK"></param>
        /// <param name="depPropertyOnDObjThatKBindsTo"></param>
        /// <param name="uSourceTrigger"></param>
        /// <param name="bMode"></param>
        /// <param name="converter"></param>
        public static void DataBindOneChildsPropertyToDepObj<K>(this K child, DependencyObject depObj, DependencyProperty depPropertyOnK, DependencyProperty depPropertyOnDObjThatKBindsTo, UpdateSourceTrigger uSourceTrigger, BindingMode bMode, IValueConverter converter)   
            where K : FrameworkElement
        {
            child.SetBinding(depPropertyOnK, new Binding
            {
                Source = depObj as DependencyObject,
                Path = new PropertyPath(depPropertyOnDObjThatKBindsTo),
                Mode = bMode,
                UpdateSourceTrigger = uSourceTrigger,
                Converter = converter
            }
            );
        }
        #endregion
        
        #endregion

    }//end of class
}//end of namespace
